﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Data.GSQL
{
    /// <summary>
    /// 原生SQL语句构建器
    /// </summary>
    public class SQLBuilder
    {
        internal SQLBuilder(SQLTextGenerator textGenerator)
        {
            this.sqlTextGenerator = textGenerator;
        }
        private readonly SQLTextGenerator sqlTextGenerator;

        /// <summary>
        /// 获取LAST_INSERT_ID的查询语句
        /// </summary>
        /// <returns></returns>
        public string SelectLastId()
        {
            if (sqlTextGenerator is MySqlTextGenerator)
            {
                return "SELECT LAST_INSERT_ID();";
            }
            else if (sqlTextGenerator is SqliteTextGenerator)
            {
                return "SELECT LAST_INSERT_ROWID();";
            }
            else if (sqlTextGenerator is MsSqlTextGenerator)
            {
                return "SELECT @@IDENTITY;";
            }
            else
            {
                throw new NotSupportedException();
            }

        }
        /// <summary>
        /// 处理WHERE语句
        /// </summary>
        /// <param name="action"></param>
        /// <param name="sb"></param>
        private void ProcessWhere(Action<QueryConditionBuilder> action, StringBuilder sb)
        {
            sb.Append(" WHERE ");
            if (action != null)
            {
                var qcb = new QueryConditionBuilder(this.sqlTextGenerator);
                action.Invoke(qcb);
                sb.Append(qcb.ToText());
            }
            else
            {
                sb.Append("(1 = 1)");
            }
        }
        /// <summary>
        /// 创建插入语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public string BuildInsert(string table, params string[] columns)
        {
            StringBuilder sb = new StringBuilder("INSERT INTO ");
            sb.Append(sqlTextGenerator.SafetiyName(table));
            sb.Append("(");
            List<string> safenames = new List<string>(columns.Length);
            List<string> values = new List<string>(columns.Length);
            foreach (var item in columns)
            {
                safenames.Add(sqlTextGenerator.SafetiyName(item));
                values.Add("@" + item);
            }
            sb.Append(string.Join(',', safenames));
            sb.Append(")VALUES(");
            sb.Append(string.Join(',', values));
            sb.Append(");");
            return sb.ToString();
        }

        /// <summary>
        /// 构建UPDATE语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public string BuildUpdate(string table, string[] columns, Action<QueryConditionBuilder> action)
        {
            StringBuilder sb = new StringBuilder("UPDATE ");
            sb.Append(sqlTextGenerator.SafetiyName(table));
            sb.Append(" SET ");
            List<string> values = new List<string>(columns.Length);
            foreach (var item in columns)
            {
                values.Add(sqlTextGenerator.SafetiyName(item) + " = @" + item);
            }
            sb.Append(string.Join(',', values));

            ProcessWhere(action, sb);

            sb.Append(";");
            return sb.ToString();
        }
        /// <summary>
        /// 构建查询语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columns">为NULL表示查询所有列</param>
        /// <param name="action"></param>
        /// <returns></returns>
        public string BuildSelect(string table, string[] columns, Action<QueryConditionBuilder> action)
        {
            StringBuilder sb = new StringBuilder("SELECT ");
            if (columns == null)
            {
                sb.Append("*");
            }
            else
            {
                List<string> cols = new List<string>(columns.Length);
                foreach (var item in columns)
                {
                    cols.Add(sqlTextGenerator.SafetiyName(item));
                }
                sb.Append(string.Join(',', cols));
            }
            sb.Append(" FROM ");
            sb.Append(sqlTextGenerator.SafetiyName(table));

            ProcessWhere(action, sb);

            sb.Append(";");
            return sb.ToString();
        }
        /// <summary>
        /// 构建删除语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public string BuildDelete(string table, Action<QueryConditionBuilder> action)
        {
            StringBuilder sb = new StringBuilder("DELETE FROM ");
             
            sb.Append(sqlTextGenerator.SafetiyName(table));

            ProcessWhere(action, sb);

            sb.Append(";");
            return sb.ToString();
        }

    }
}
